import axios from 'axios';
import { ElMessage } from 'element-plus';
import router from '@/router';

// 获取环境变量中的API地址，如果没有则使用默认值
const baseURL = process.env.VUE_APP_API_URL || 'http://localhost:8000';

// 用于防止重复处理401错误
let isHandling401 = false;
let handle401Timeout = null;

// 创建axios实例
const service = axios.create({
  baseURL,
  timeout: 120000 // 请求超时时间设置为 2 分钟
});

// 不需要认证的接口列表
const publicEndpoints = [
  {
    path: '/api/auth/token',  // 登录接口
    methods: ['POST']         // 只允许 POST 方法不需要认证
  },
  // {
  //   path: '/api/public',      // 公共接口前缀
  //   methods: ['GET', 'POST']  // GET 和 POST 方法都不需要认证
  // },
  {
    path: '/api/shop/',        // 店铺列表接口（精确匹配，不包含子路径）
    methods: ['GET', 'POST'], // GET 和 POST 方法都不需要认证
    exact: true              // 精确匹配标志
  },
  {
    path: '/api/shop/update_enable_t/',        // 店铺启用接口（精确匹配，不包含子路径）
    methods: ['PUT'], // PUT 方法不需要认证
    exact: false              // 精确匹配标志
  },
  {
    path: '/api/shop/update_enable_f/',        // 店铺禁用接口（精确匹配，不包含子路径）
    methods: ['PUT'], // PUT 方法不需要认证
    exact: false              // 精确匹配标志
  },
  {
    path: '/api/shop/products/',        // 店铺商品接口（精确匹配，不包含子路径）
    methods: ['GET'], // GET 方法不需要认证
    exact: false              // 精确匹配标志
  },
  {
    path: '/api/brand/',        // 店铺商品接口（精确匹配，不包含子路径）
    methods: ['GET', 'POST'], // GET 和 POST 方法都不需要认证
    exact: true              // 精确匹配标志
  },
  {
    path: '/api/wingknife/processes/run_pass',        // 影刀流程运行接口
    methods: ['POST'], // POST 方法不需要认证
    exact: false              // 前缀匹配，包含子路径
  },
  {
    path: '/api/sku/clean-sku-data',        // 影刀流程运行接口
    methods: ['POST'], // POST 方法不需要认证
    exact: true              // 前缀匹配，包含子路径
  }
];

// 确保JSON数据中不包含数字键的函数
function sanitizeData(data) {
  if (!data || typeof data !== 'object') return data;
  
  // 处理数组
  if (Array.isArray(data)) {
    return data.map(item => sanitizeData(item));
  }
  
  // 处理对象
  const cleanData = {};
  Object.keys(data).forEach(key => {
    const value = data[key];
    // 确保键是字符串，并递归处理嵌套对象和数组
    cleanData[String(key)] = sanitizeData(value);
  });
  
  return cleanData;
}

// 增强版的预处理函数，处理JSON字符串中的数字键
function preprocessJsonFields(data) {
  if (!data) return data;
  
  // 如果是FormData，不做处理
  if (data instanceof FormData) return data;
  
  // 遍历对象的所有属性
  if (typeof data === 'object' && !Array.isArray(data)) {
    const newData = { ...data };
    
    for (const key in newData) {
      const value = newData[key];
      
      // 如果值是字符串，且看起来像JSON
      if (typeof value === 'string' && 
          ((value.startsWith('{') && value.endsWith('}')) || 
          (value.startsWith('[') && value.endsWith(']')))) {
        try {
          // 尝试解析JSON
          const parsedValue = JSON.parse(value);
          // 清理JSON并重新序列化
          newData[key] = JSON.stringify(sanitizeData(parsedValue));
        } catch (e) {
          // 如果解析失败，保持不变
        }
      } else if (typeof value === 'object') {
        // 递归处理嵌套对象
        newData[key] = preprocessJsonFields(value);
      }
    }
    return newData;
  }
  
  return data;
}

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 添加调试日志
    console.log('发送请求:', {
      url: config.url,
      method: config.method,
      data: config.data instanceof FormData ? 'FormData对象' : config.data,
      headers: config.headers
    });
    
    // 检查是否是公共接口
    const isPublicEndpoint = publicEndpoints.some(endpoint => {
      const methodMatch = endpoint.methods.includes(config.method.toUpperCase());
      const pathMatch = endpoint.exact 
        ? config.url === endpoint.path  // 精确匹配
        : config.url.startsWith(endpoint.path);  // 前缀匹配
      return methodMatch && pathMatch;
    });
    
    // 如果不是公共接口，添加token
    if (!isPublicEndpoint) {
      const token = localStorage.getItem('token');
      if (token) {
        config.headers['Authorization'] = `Bearer ${token}`;
      }
    }
    
    // 对于登录请求，使用表单格式
    if (config.url === '/api/auth/token') {
      config.method = 'post';
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
      const formData = new URLSearchParams();
      const data = config.data || {};
      for (const key in data) {
        formData.append(key, data[key]);
      }
      config.data = formData;
      
      console.log('登录请求数据:', {
        url: config.url,
        method: config.method,
        formData: formData.toString(),
        headers: config.headers
      });
    }
    
    return config;
  },
  error => {
    console.error('请求配置错误:', error);
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  response => {
    const res = response.data
    // 如果返回的状态码不是200，说明接口请求有误
    if (response.status !== 200) {
      ElMessage({
        message: res.message || '请求失败',
        type: 'error',
        duration: 5 * 1000
      })
      return Promise.reject(new Error(res.message || '请求失败'))
    } else {
      return res
    }
  },
  error => {
    console.error('请求错误:', error)
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // token 失效，清除用户信息并跳转到登录页
          localStorage.removeItem('token')
          localStorage.removeItem('user')
          ElMessage.error('登录已过期，请重新登录')
          // 使用 router 进行跳转
          window.location.href = '/login'
          break
        case 403:
          ElMessage.error('没有权限访问该资源')
          break
        case 404:
          ElMessage.error('请求的资源不存在')
          break
        case 500:
          ElMessage.error('服务器错误')
          break
        default:
          ElMessage.error(error.response.data.message || '请求失败')
      }
    } else if (error.request) {
      ElMessage.error('网络错误，请检查您的网络连接')
    } else {
      ElMessage.error('请求配置错误')
    }
    return Promise.reject(error)
  }
)

export default service; 